package hku.cs.eclunuo;

import hku.cs.eclunuo.builders.SootBuilder;
import hku.cs.eclunuo.nature.SootNature;

import java.io.IOException;
import java.net.URL;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 */
public class LunuoPlugin extends AbstractUIPlugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "hku.cs.lunuo";
	private MessageConsole console = new MessageConsole("Lunuo Console", null);
	private IPreferenceStore preferenceStore;
	public static final QualifiedName FILTER_NOINSTRU_TARGET_PROPERTY = new QualifiedName(LunuoPlugin.PLUGIN_ID, "filter_no_instru_pack");
	public static final QualifiedName LIGHT_BUILDER = new QualifiedName(LunuoPlugin.PLUGIN_ID, "light_builder");
	public static final IPath METADIR;
	public IPath ICONPATH = new Path("icons");
	public IPath PLUGINPATH;
	// The shared instance
	private static LunuoPlugin plugin;
	
	static{		
		METADIR = ResourcesPlugin.getWorkspace().getRoot().getLocation().append("/.metadata/.plugins/"+PLUGIN_ID+"/");	
	}
	
	/**
	 * The constructor
	 */
	public LunuoPlugin() {
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		
		ConsolePlugin.getDefault().getConsoleManager().addConsoles(
		    new IConsole[]{console});
	}

	@Override
	public IPreferenceStore getPreferenceStore() {
		if (preferenceStore == null) {
            preferenceStore = new ScopedPreferenceStore(new InstanceScope(),getBundle().getSymbolicName());

        }
        return preferenceStore;
	}
	
	public static Shell getActiveWorkbenchShell() {
		IWorkbenchWindow workBenchWindow= getActiveWorkbenchWindow();
		if (workBenchWindow == null)
			return null;
		return workBenchWindow.getShell();
	}

	/**
	 * Returns the active workbench window
	 * 
	 * @return the active workbench window
	 */
	public static IWorkbenchWindow getActiveWorkbenchWindow() {
		if (plugin == null)
			return null;
		IWorkbench workBench= plugin.getWorkbench();
		if (workBench == null)
			return null;
		return workBench.getActiveWorkbenchWindow();
	}

	public static IWorkbenchPage getActivePage() {
		IWorkbenchWindow activeWorkbenchWindow= getActiveWorkbenchWindow();
		if (activeWorkbenchWindow == null)
			return null;
		return activeWorkbenchWindow.getActivePage();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
		console = null;
	}

	/**
	 * Returns the shared instance
	 *
	 * @return the shared instance
	 */
	public static LunuoPlugin getDefault() {
		return plugin;
	}

	public MessageConsole getConsole() {
		return console;
	}
	
	public void addSootNature(final IProject project, boolean asy){
		try {
			if(project.hasNature(SootNature.NATURE_ID))
				return;
			IProjectDescription description = project.getDescription();
			String[] natures = description.getNatureIds();

			String[] newNatures = new String[natures.length + 1];
			System.arraycopy(natures, 0, newNatures, 0, natures.length);
			newNatures[natures.length] = SootNature.NATURE_ID;
			description.setNatureIds(newNatures);
			project.setDescription(description, null);
			
			if (asy) {
				new Job("soot builder job") {
					protected IStatus run(IProgressMonitor monitor) {
						try {
							project.build(SootBuilder.FULL_BUILD,
									SootBuilder.BUILDER_ID, null, null);
						} catch (CoreException e) {
							LunuoLog.logError(e);
						}
						return Status.OK_STATUS;
					}
				}.schedule();
			} else
				project.build(SootBuilder.FULL_BUILD,
						SootBuilder.BUILDER_ID, null, null);
			
			
		} catch (CoreException e) {
			e.printStackTrace();
		}	
		
	}
	
	public void removeSootNature(final IProject project){
		try {
			if(!project.hasNature(SootNature.NATURE_ID))
				return;
			
			IProjectDescription description = project.getDescription();
			String[] natures = description.getNatureIds();

			for (int i = 0; i < natures.length; ++i) {
				if (SootNature.NATURE_ID.equals(natures[i])) {
					// Remove the nature
					String[] newNatures = new String[natures.length - 1];
					System.arraycopy(natures, 0, newNatures, 0, i);
					System.arraycopy(natures, i + 1, newNatures, i,
							natures.length - i - 1);
					description.setNatureIds(newNatures);
					project.setDescription(description, null);
					return;
				}
			}
		}catch (CoreException e) {
			e.printStackTrace();
		}
	}
	
	public ImageDescriptor getImageDescriptor(String relativePath) {
		IPath path= ICONPATH.append(relativePath);
		return createImageDescriptor(getDefault().getBundle(), path, true);
	}
	
	private ImageDescriptor createImageDescriptor(Bundle bundle, IPath path, boolean useMissingImageDescriptor) {
		URL url= FileLocator.find(bundle, path, null);
		if (url != null) {
			return ImageDescriptor.createFromURL(url);
		}
		if (useMissingImageDescriptor) {
			return ImageDescriptor.getMissingImageDescriptor();
		}
		return null;
	}


	private IPath getPluginPath() {
		try {
			return new Path(FileLocator.getBundleFile(LunuoPlugin.getDefault().getBundle()).getPath());
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	


}
